<template>
    <div>
      <!-- 
        code: "Acl" // 标识名称
        deleted: false
        gmtCreate: "2020-11-30 16:40:08"
        gmtModified: "2020-11-30 16:40:08"
        id: "1333329957008228353"
        level: 2
        name: "权限管理"
        pid: "1" // 所属节点的id
        select: false
        status: null
        toCode: ""
        type: 1  // 1: 路由 2: 按钮
        children: []
      -->
      <!-- 
        code: "btn.Role.assgin"
        deleted: false
        gmtCreate: "2020-11-30 16:50:13"
        gmtModified: "2020-12-01 08:13:47"
        id: "1333332492158812161"
        level: 4
        name: "分配权限"
        pid: "1333330152781561858"
        select: false
        status: null
        toCode: "RoleAuth"
        type: 2
       -->
      <el-table
        border
        style="margin-bottom: 20px;"
        :data="menuPermissionList"
        :expand-row-keys="expandKeys"
        row-key="id"
      >
        <el-table-column
          prop="name"
          label="名称"
        />
        <el-table-column
          prop="code"
          label="权限值"
        />
  
        <el-table-column
          prop="toCode"
          label="跳转权限值"
        />
  
        <el-table-column label="操作">
          <template v-slot="{row}">
            
            <el-button
              :disabled="row.level===4"
              type="primary"
              :icon="Plus"
              size="small"
              @click="toAddPermission(row)"
              :title="getAddTitle(row.level)"
            />
  
            <el-button
              type="primary"
              :icon="Edit"
              size="small"
              :disabled="row.level===1"
              @click="toUpdatePermission(row)"
              :title="row.level===4 ? '修改功能' : '修改菜单'"
            />
  
            <el-button
              :disabled="row.level===1"
              type="danger"
              :icon="Delete"
              size="small"
              @click="removePermission(row)"
              title="删除"
            />
          </template>
        </el-table-column>
      </el-table>
  
      <el-dialog 
        v-model="dialogVisible" 
        :title="dialogTitle" 
        @close="resetData">
  
        <el-form ref="permissionRef" :model="permission" :rules="permissionRules" label-width="120px">
          <el-form-item label="名称" prop="name">
            <el-input v-model="permission.name"/>
          </el-form-item>
          
          <el-form-item label="功能权限值" prop="code">
            <el-input v-model="permission.code"/>
          </el-form-item>
  
          <el-form-item label="跳转路由权限值" prop="toCode" v-if="permission.level===4">
            <el-input v-model="permission.toCode"/>
          </el-form-item>
        </el-form>
        
        <template #footer>
          <el-button @click="resetData">取 消</el-button>
          <el-button type="primary" @click="addOrUpdatePermission">确 定</el-button>
        </template>
      </el-dialog>
    </div>
  </template>
  
  <script lang="ts">
    export default {
      name: 'Permission',
    };
  </script>
  
  <script lang="ts" setup>
    import { ElTable, ElTableColumn, ElButton, ElDialog, ElForm, ElFormItem, ElInput, type FormInstance, ElMessage, ElMessageBox } from "element-plus";
    import {Plus, Edit, Delete} from '@element-plus/icons-vue'
    import { reactive, ref, computed, onMounted, nextTick } from "vue";
    import type { PermissionListModel, PermissionModel, PermissionLevelModel } from "@/api/acl/model/permissionModel";
    import { getPermissionListApi, removePermissionApi, saveOrUpdatePermissionApi } from "@/api/acl/permission";
    const permissionRef = ref<FormInstance>()
  
    const menuPermissionList = ref<PermissionListModel>([])
    const expandKeys = ref<string[]>([])
    const dialogVisible = ref<boolean>(false)
    const permission = reactive<PermissionModel>({ // 要操作的菜单权限对象
          type: 1,
          level: 0,
          name: '',
          code: '',
          toCode: ''
    })
  
    onMounted(() => {
      fetchPermissionList()
    })
  
    /* 
    动态计算得到Dialog的标题
    */
    const dialogTitle = computed(() => {
      const {id, level} = permission
      if (id) {
        return level===4 ? '修改功能' : '修改菜单'
      } else {
        return level===4 ? '添加功能' : '添加菜单'
      }
    })
  
    /* 
    根据权限的等级来计算确定校验规则
    */
    const permissionRules = computed(() => {
      // 菜单权限校验的规则
      const menuRules = { 
        name: [{required: true, message: '名称必须输入'}],
        code: [{required: true, message: '权限值必须输入'}],
      }
      // 按钮功能权限校验的规则
      const btnRules = { 
        name: [{required: true, message: '名称必须输入'}],
        code: [{required: true, trigger: 'blur', message: '功能权限值必须输入'}]
      }
      console.log('permissionRules')
      return permission.level===4 ? btnRules : menuRules
    })
  
    /* 
    根据级别得到要显示的添加dialog的标题
    */
    const getAddTitle = (level: number) => {
      if (level===1 || level===2) {
        return '添加菜单'
      } else if (level===3){
        return '添加功能'
      }
    }
  
    /* 
    请求获取权限菜单数据列表
    */
    const fetchPermissionList = async () => {
      const result = await getPermissionListApi()
      menuPermissionList.value = result.children
      expandKeys.value = [menuPermissionList.value[0].id as string]
    }
  
    /* 
    显示添加权限的界面(菜单或功能)
    */
    const toAddPermission = (row: PermissionModel) => {
      dialogVisible.value = true
      permission.pid = row.id    // pid ==> parentId 父权限数据的id
      permission.level = (row.level + 1) as PermissionLevelModel
      permission.type = permission.level===4 ? 2 : 1
      
      // 清除校验(必须在界面更新之后)
      // 注意: 校验规则是动态的, nextTick清除后还会显示错误信息, 应该是在nextTick后进行了校验
      /* nextTick(() => {
        console.log('nextTick')
        permissionRef.value?.clearValidate()
      }) */
      setTimeout(() => {
        permissionRef.value?.clearValidate()
      }, 0);
    }
  
    /* 
    显示菜单添加或更新的dialog
    */
    const toUpdatePermission = (row: PermissionModel) => {
      dialogVisible.value = true
      Object.assign(permission, row)
      permission.type = permission.level===4 ? 2 : 1
  
      // 清除校验(必须在界面更新之后)
      // nextTick(() => permissionRef.value?.clearValidate())
      setTimeout(() => {
        permissionRef.value?.clearValidate()
      }, 0);
    }
  
    /* 
    删除某个权限节点
    */    
    const removePermission = (permission: PermissionModel) => {
      
      ElMessageBox.confirm('此操作将永久删除该记录, 是否继续?', '提示', {
        type: 'warning'
      }).then(async () => {
        await removePermissionApi(permission.id as string)
        ElMessage.success('删除成功!')
        fetchPermissionList()
      }).catch((error) => {
        if (error==='cancel') {
          ElMessage({
            type: 'info',
            message: '已取消删除'
          })
        }
      })
    }
  
    /* 
    添加或更新功能权限
    */
    const addOrUpdatePermission = () => {
      permissionRef.value?.validate(async valid => {
        if (valid) {
          const { id } = permission
  
          await saveOrUpdatePermissionApi(permission)
          ElMessage.success(`${id ? '修改' : '添加'}成功!`)
          resetData()
          fetchPermissionList()
        }
      })
    }
  
    /* 
    重置数据
    */
    const resetData = () => {
      dialogVisible.value = false
      Object.assign(permission, {
        type: 1,
        level: 0,
        name: '',
        code: '',
        toCode: ''
      })
    }
  
  </script>
  